﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace XTYAPI.通讯
{
    public class TCPServerAsyn
    {
        private Socket tcpServer;
        public int MaxComCount { get; set; } = 5;
        public List<Socket> SocketList { get; private set; } = new List<Socket>();

        public event Action<Socket, byte[], int> Recive;
        public bool StartListen(string ip, int port)
        {
            IPAddress iPAddress;
            if (string.IsNullOrEmpty(ip.Trim()))
            {
                iPAddress= IPAddress.Any;
            }
            else
            {
                iPAddress = IPAddress.Parse(ip);
            }
            tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //tcpServer.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,2000);
            tcpServer.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 2000);
            IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, port);
            try
            {
                tcpServer.Bind(iPEndPoint);
                tcpServer.Listen(5);
                Task.Run(() =>
                {
                    ListenConnection();
                });
            }
            catch (Exception  ex)
            {
                return false; 
            }
            return true;
        }

        private void ListenConnection()
        {
            while (true)
            {
                try
                {
                    Socket tcpClient = tcpServer.Accept();
                    if (SocketList.Count< MaxComCount)
                    {                
                        SocketList.Add(tcpClient);

                        //多线程
                        Task.Run(new Action(() =>
                        {
                            ReceiveFrom(tcpClient);
                        }));
                    }
                    else
                    {
                        tcpClient.Send(Encoding.ASCII.GetBytes($"Maximum connection {MaxComCount}"));
                        Thread.Sleep(3000);
                        tcpClient.Close();
                    }                 
                }
                catch (Exception)
                {

                    break;
                }
            }
        }
        private void ReceiveFrom(Socket tcpClient)
        {
            while (true)
            {
                byte[] buffer = new byte[1024 * 1024 * 10];

                int length = -1;

                string client = tcpClient.RemoteEndPoint.ToString();
                if (tcpClient.Poll(-1,SelectMode.SelectRead))
                {
                    try
                    {
                        length = tcpClient.Receive(buffer);
                        if (length==0)
                        {
                            //正常断开
                            SocketList.Remove(tcpClient);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        SocketList.Remove(tcpClient);
                        break;
                    }
                    if (length > 0)
                    {
                        Recive?.Invoke(tcpClient, buffer, length);
                    }
                }
            }
        }
        public void SendALL()
        {
            foreach (var item in SocketList)
            {
                try
                {
                    if (item.Connected)
                    {
                        item.Send(Encoding.ASCII.GetBytes($"Send IP{((IPEndPoint)item.LocalEndPoint).ToString()}    Recive IP{((IPEndPoint)item.RemoteEndPoint).ToString()})"));
                    }
                }
                catch (Exception ex)
                {
                    
                }
              
            }
        }

    }
}
